#ifndef __FUNC__
#define __FUNC__

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include <dirent.h>
#include <time.h>
#include <pthread.h>
#include <libgen.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#include "font.h"
#include "jpeglib.h"
#include <linux/input.h> 


#define LCD_PATH    "/dev/fb0"
#define TS_PATH     "/dev/input/event0"
struct fb_var_screeninfo varinfo; // 可变属性

/*定义链表节点模型*/
typedef struct Music 
{
    char name[100];//视频或音频的名字
    int num;//编号
    struct Music *prev;//前驱指针
    struct Music *next;//后驱指针
}D_music,*pD_music;

struct input_event ts_event2;//触摸屏信息的存储结构2---音量线程
struct input_event ts_event3;//触摸屏信息的存储结构3---进度线程
int ts_fd1;//触摸屏地址1
int ts_fd2;//触摸屏地址2
int ts_fd3;//触摸屏地址3
int fd;//lcd指针
int* map;//映射指针
int count;//读取到的数量
int fd_fifo;//管道文件
int mplayer;//maplayer=1表示播放器已启动，maplayer=0表示播放器未启动
int music_volume;//音量大小-- 0-100
int mplayer_mute;//=1表示播放器已静音
int music_next;//=1表示用户进行了上一首下一首的操作
int music_move;//=1表示用户进行了快退或拖动进度条左移的操作
int mplayer_stop;//=1表示播放器暂停，=0表示没有暂停
int time_length;//正在播放的音频或视频总时长
int time_pos;//音频或视频播放的当前时长
int musiclist;//表示播放列表当前编号
int video_num;//记录视频的编号
int music_init;//区分开视频和音乐的还原
struct Music *head;
struct Music *music;//全局变量，存储music_head
int clean;//刷新歌词
pD_music video_head;//视频链表头

char recvbuffer[1024];

int x_s;//x起始坐标
int x_e;//x终点坐标
int y_s;//y起始坐标

int y_e;//y终点坐标

static int score;//分数
int game_map[4][4];//2048数据数组

pthread_t tid1,tid2,tid3,tid4,tid5,tid6;//线程号
pthread_attr_t attr;//设置属性
FILE *fp_mplayer;//播放器输出的信息
pthread_mutex_t mutex;//互斥锁

//上下左右划动、点击触摸屏，设置成枚举
enum SlidDire { UP , DOWN ,  LEFT, RIGHT ,CLICK};

/**
 * @brief 初始化
 * @return 成功返回0 失败返回-1
*/
int Init();
/**
 * @brief 初始化变量
 * @return 成功返回0 
*/
int Data_Init();
/**
 * @brief 链表初始化
 * @param dirname 指定的路径，用于检索
 * @return 成功返回pD_music的头节点 失败返回-1
*/
pD_music List_Init(const char *dirname);
/**
 * @brief 链表创建
 * @return 成功返回pD_music的头节点 失败返回NULL
*/
pD_music List_Create();
/**
 * @brief 尾插
 * @param head 链表的头节点
 * @param pic_name 插入的文件名
 * @param num 插入的编号
 * @return 成功返回true 失败返回false
*/
bool List_Insert_End(pD_music head, char *pic_name , int num);
/**
 * @brief 检索目录
 * @param dirname 指定的路径，用于检索
 * @param music_list 存储内容的链表
 * @return 成功返回0 失败返回-1
*/
int FindDir( const char *dirname , pD_music music_list );
/**
 * @brief 遍历链表
 * @param music_head 链表的头节点
 * @return 无返回值
*/
void List_DisPlay(pD_music music_head);
/**
 * @brief 销毁链表
 * @param Head 链表的头节点
 * @return 成功返回销毁的结点个数
*/
int List_Destory(pD_music Head);
/**
 * @brief 线程1--实时显示音量进度条
 * @return 返回就退出
*/
void *Pthread_Show_Volume(void *arg);
/**
 * @brief 线程2--实时拖动音量进度条
 * @return 返回就退出
*/
void *Pthread_Drag_Volume(void *arg);
/**
 * @brief 线程3--实时显示进度条
 * @return 返回就退出
*/
void *Pthread_Show_ProGress_Bar(void *arg);
/**
 * @brief 线程4--实时拖动进度条
 * @return 返回就退出
*/
void *pthread_show_lrc(void *arg);
/**
* @brief 线程5--实时显示歌词
* @return 返回就退出
*/

void *Pthread_Drag_ProGress_Bar(void *arg);
/**
 * @brief 音乐界面初始化
 * @return 成功返回0
*/
int Music_InterFace_Init();
/**
 * @brief 无特效显示jpg图片
 * @param map 映射后内存地址的入口 
 * @param FilePath jpg图片的文件名或者路径名
 * @param strat_x 显示图片的起始x坐标
 * @param start_y 显示图片的起始y坐标
 * @param scale_num 显示倍数的分子
 * @param scale_denom 显示倍数的分母
 * @return 成功返回0 失败返回1
*/
int ShowJpg(int * map , const char * FilePath , int strat_x , int start_y , int scale_num, int scale_denom);
/**
 * @brief 根据传入的数据进行涂色
 * @param x_start 涂色的起始x坐标 
 * @param y_start 涂色的起始y坐标 
 * @param length 高度
 * @param width 宽度
 * @param color 颜色
 * @return 无返回值
*/
void Lcd_Show_Color(int x_start,int y_start,int length,int width,int color);
/**
 * @brief 发送命令
 * @param buf 存储命令的数组
 * @return 无返回值
*/
void Send_Command(char buf[]);
/**
 * @brief 获取起点和终点坐标
 * @return 成功返回0
*/
int Get_side();
/**
 * @brief 分析坐标，判断做了什么动作
 * @return 成功返回动作 UP , DOWN ,  LEFT, RIGHT ,CLICK，并被定义为枚举
*/
int Analyze_Coordinates();
/**
 * @brief 分析坐标，判断在音乐界面点击了什么功能
 * @return 成功返回1--播放/暂停 2--上一首 3--下一首 4--后退 5--快进 6--上一页 7--下一页 8--倍速 9--静音
*/
int Analyze_Music_Coordinates();
/**
 * @brief 播放视频
 * @param music_head 传入存储需要播放的内容的链表
 * @return 成功返回0
*/
int Music_Play(pD_music music_head);
/**
 * @brief 显示播放列表
 * @param lst 列表页数数量
 * @param music_head 传入存储需要播放的内容的链表
 * @return 无返回值
*/
void Show_List(int *lst , pD_music music_head);
/**
 * @brief 上一首
 * @param music_head 传入存储需要播放的内容的链表
 * @return 无返回值
*/
void Music_prev(pD_music music_head);
/**
 * @brief 下一首
 * @param music_head 传入存储需要播放的内容的链表
 * @return 无返回值
*/
void Music_Next(pD_music music_head);
/**
 * @brief 快进  后退
 * @param mv_val 快进/后退的幅度 1-xxx
 * @return 无返回值
*/
void Music_Seek(int mv_val);
/**
 * @brief 倍速
 * @param music_head 传入存储需要播放的内容的链表
 * @return 无返回值
*/
void Music_Speed(pD_music music_head);
/**
 * @brief 静音
 * @return 无返回值
*/
void Mute_Volume();
/**
 * @brief 上一页
 * @param musiclist 当前列表页数
 * @param music_head 传入存储需要播放的内容的链表
 * @return 返回0
*/
int Prev_List(int *musiclist , pD_music music_head);
/**
 * @brief 下一页
 * @param musiclist 当前列表页数
 * @param music_head 传入存储需要播放的内容的链表
 * @return 返回0
*/
int Next_List(int *musiclist , pD_music music_head);
/**
 * @brief 暂停
 * @return 返回0
*/
int VStatus();
/**
 * @brief 调节亮度
 * @param brightness 调节的幅度
 * @return 返回0
*/
int VBright(int brightness);
/**
 * @brief 寻找mv播放
 * @param music_head 音乐链表
 * @param video_head 视频链表
 * @return 返回0
*/
int Mv_Play(pD_music music_head , pD_music video_head);
/**
 * @brief 进入2048
 * @param map 映射后内存地址的入口
 * @return 返回0
*/
int Into2048();

/**
 * @brief （变强之后）进入2048
 * @param map 映射后内存地址的入口
 * @return 返回0
*/
int Into2048_power();

/**
 * @brief 初始化2048
 * @param map 映射后内存地址的入口
 * @return 无返回值
*/
void game_init();

/**
 * @brief 显示分数
 * @param map 映射后内存地址的入口
 * @param new_score 新分数
 * @return 无返回值
*/
void display_score(int new_score);

/**
 * @brief 产生新的数字
 * @param map 映射后内存地址的入口
 * @return 失败返回-1
*/
int  new_node();

/**
 * @brief （变强之后）产生新的数字
 * @param map 映射后内存地址的入口
 * @return 失败返回-1
*/
int  new_node_power();

/**
 * @brief 判断有没有空位
 * @return 成功返回true 失败返回false
*/
bool is_full( );

/**
 * @brief 刷新分数显示
 * @param map 映射后内存地址的入口
 * @return 成功返回0
*/
int show_map();

/**
 * @brief 开始游戏
 * @param map 映射后内存地址的入口
 * @return 无返回值
*/
void game_start();

/**
 * @brief （变强之后）开始游戏
 * @param map 映射后内存地址的入口
 * @return 无返回值
*/
void game_start_power();

/**
 * @brief 右移
 * @return 成功返回0
*/
int do_right ();

/**
 * @brief 左移
 * @return 成功返回0
*/
int do_left ();

/**
 * @brief 上移
 * @return 成功返回0
*/
int do_up ();

/**
 * @brief 下移
 * @return 成功返回0
*/
int do_down ();
/**
 * @brief 进入密码界面
 * @return 成功返回0
*/
int Password_Interface();
/**
 * @brief 消除线程初始化
 * @return 无返回值
*/
void ExitTid();
/**
 * @brief 退出总程序
 * @return 无返回值
*/
void ExitLcd();
#endif